package cn.parus.commons.utils;

import java.util.concurrent.ThreadLocalRandom;

/**
 * @Author: Axel
 * @Description: TODO 均匀过期时间工具，防止Reids雪崩
 **/
public class TimeoutUtil {
    // 默认过期时间是一小时
    private static final int DEFAULT_BASE_EXPIRE = 3600;
    // 默认最小波动因子是0.8
    private static final float MIN_FACTOR = 0.8f;
    // 默认最大波动因子是1.2
    private static final float MAX_FACTOR = 1.2f;

    private TimeoutUtil() {
        throw new IllegalStateException("该工具类禁止实例化");
    }

    /**
     * 根据指定基础时间生成随机过期时间
     * @param baseExpire 基础过期时间（单位秒，必须大于0）
     * @return 在[base*0.8, base*1.2]范围内得随机过期时间
     */
    public static int getRandomExpire(int baseExpire) {
        if (baseExpire <= 0) {
            throw new IllegalArgumentException("过期时间必须为整数");
        }

        // 生成随机波动因子
        float factor = ThreadLocalRandom.current().nextFloat(MIN_FACTOR, MAX_FACTOR);
        int randomExpire = (int) (baseExpire * factor);

        // 返回值至少为一秒
        return Math.max(randomExpire, 1);
    }

    /**
     * 自定义波动范围生成随机过期时间
     * @param baseExpire 基础过期时间（秒）
     * @param minFactor 最小波动因子（如0.9）
     * @param maxFactor 最大波动因子（如1.1）
     */
    public static int getRandomExpire(int baseExpire, float minFactor, float maxFactor) {
        if (baseExpire <= 0) {
            throw new IllegalArgumentException("过期时间必须为整数");
        }
        if (minFactor >= maxFactor) {
            throw new IllegalArgumentException("无效得因子范围");
        }

        float factor = ThreadLocalRandom.current().nextFloat(minFactor, maxFactor);
        int randomExpire = (int) (baseExpire * factor);
        return Math.max(randomExpire, 1);
    }
}
